Die programmierbare Pipeline enthält alle programmierbaren Komponenten
der Rendering-Pipeline, also die relativ neuen Pixel-
und Vertexshader.
Diese ermögliche durch ihre beliebige
Programmierbarkeit, zudem in der Hardware,
eine riesige Anzahl neuer Effekte – im Gegensatz zur
starren Pipeline – und das mit
guter Performance.
Ein Nachteil dieser Shader ist jedoch, dass sie in
Assembler programmiert werden,
was sehr aufwändig ist. Außerdem beherrscht nicht
jeder Programmierer
diese Sprache. Jedoch gibt es mittlerweile
(eigentlich schon länger) sogenannte
Shadersprachen, die speziell zur Programmierung
dieser Shader entwickelt
werden. Aktuelles Beispiel: Cg von Nvidia.
Gerendert mit Hilfe des
Pixelshaders
Eine Sinusfunktion auf die einzelnen Vertices
angewandt bringt solch ein Ergebnis
Es folgt ein
Codebeispiel von den Microsoftseiten, ab dem Kürzel asm
im Quelltext beginnt der Assemblercode für den
Vertexshader, hier
die
Version 1.1 .
//
// Effect File Workshop Exercise 5
// Copyright (c) 2000 Microsoft Corporation. All rights reserved.
//
vector lhtR; // Light direction
matrix mWld; // World
matrix mTot; // Total
vector matD; // Material diffuse
vector matS; // Material specular
vector vCPS; // Camera position
// Background color
DWORD BCLR = 0xFF000000;
pixelshader pNIL;
string XFile = "f40.x";
// Technique names for display in viewer window
string tec0 = "Exercise 5: Vertex Shader Specular Lighting";
technique tec0
{
pass p0
{
// Load matrices
VertexShaderConstant[0] = ; // World Matrix
VertexShaderConstant[4] = ; // World*View*Proj Matrix
// Material properties of object
VertexShaderConstant[9] =; // Diffuse
VertexShaderConstant[10] = ; // Specular
VertexShaderConstant[11] = (0.0f,0.0f,0.0f,0.0f); // Ambient
// Properties of light
VertexShaderConstant[13] = (1.0f,0.0f,0.0f,1.0f); // Diffuse
VertexShaderConstant[14] = (0.0f,0.0f,0.0f,0.0f); // Specular
VertexShaderConstant[15] = (0.0f,0.0f,0.0f,0.0f); // Ambient
VertexShaderConstant[16] = ; // Light direction
// Blending Constants
VertexShaderConstant[20] = (0.7f,0.7f,0.7f,0.7f);
VertexShaderConstant[21] = (0.3f,0.3f,0.3f,0.3f);
// Camera Information.
VertexShaderConstant[24] = ;
ColorOp[0] = SelectArg1;
ColorArg1[0] = Diffuse;
AlphaOp[0] = SelectArg1;
AlphaArg1[0] = Diffuse;
ColorOp[1] = Disable;
AlphaOp[1] = Disable;
VertexShader =
decl
{
stream 0;
float v0[3]; // Position
float v3[3]; // Normal
float v7[3]; // Texture coord1
float v8[3]; // Texture coord2
}
asm
{
vs.1.1 // Version number
m4x4 oPos, v0, c4 // Transform point to projection space
m4x4 r0,v0,c0 // Transform point to world space
add r0,-r0,c24 // Get a vector toward the camera position
// This is the negative of the camera direction
// Normalize
dp3 r11.x,r0.xyz,r0.xyz // Load the square into r1
rsq r11.xyz,r11.x // Get the inverse of the square
mul r0.xyz,r0.xyz,r11.xyz // Multiply, r0 = -(camera vector)
add r2.xyz,r0.xyz,-c16 // Get half angle
// Normalize
dp3 r11.x,r2.xyz,r2.xyz // Load the square into r1
rsq r11.xyz,r11.x // Get the inverse of the square
mul r2.xyz,r2.xyz,r11.xyz // Multiply, r2 = HalfAngle
m3x3 r1,v3,c0 // Transform normal to world space, put in r1
// r2 = half angle, r1 = normal, r3 (output) = intensity
dp3 r3.xyzw,r1,r2
// Now raise it several times
mul r3,r3,r3 // 2nd
mul r3,r3,r3 // 4th
mul r3,r3,r3 // 8th
mul r3,r3,r3 // 16th
// Compute diffuse term
dp3 r4,r1,-c16
// Blend it in
mul r3,c20,r3 // Kd
mul r4,r4,c21 // Ks
mul r4,r4,c10 // Specular
mad r4,r3,c9,r4 // Diffuse
mov oD0,r4 // Put into Diffuse Color
};
}
}